#include "SDL.h"
#include "SDL_image.h"
#include <string>
#include <fstream>
#include <algorithm>
#include <iostream>

//Screen attributes
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;

//The frame rate
const int FRAMES_PER_SECOND = 20;

//The dot dimensions
const int BLOCK_WIDTH = 20;
const int BLOCK_HEIGHT = 20;

const int BG_WIDTH = 10;
const int BG_HEIGHT = 20;

//The surfaces
Uint32 block = NULL;
SDL_Surface *screen = NULL;

//The event structure
SDL_Event event;

int bgArray[BG_HEIGHT][BG_WIDTH];
// black, cyan, blue, orange, yellow, green, purple, red
Uint8 colors[8][3] = {
	0x00, 0x00, 0x00,
	0x00, 0xFF, 0xFF,
	0x00, 0x00, 0xFF,
	0xFF, 0xA5, 0x00,
	0xFF, 0xFF, 0x00,
	0x00, 0xFF, 0x00,
	0x80, 0x00, 0x80,
	0xFF, 0x00, 0x00
};

bool init()
{
	//Initialize all SDL subsystems
	if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
	{
		return false;
	}

	//Set up the screen
	screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );

	//If there was an error in setting up the screen
	if( screen == NULL )
	{
		return false;
	}

	//Set the window caption
	SDL_WM_SetCaption( "Tetris Clone", NULL );

	for(int i=0; i<BG_HEIGHT; i++)
		std::fill(bgArray[i], bgArray[i]+BG_WIDTH, 0);

	//If everything initialized fine
	return true;
}

bool showBg()
{
	block = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
	SDL_FillRect(screen, &screen->clip_rect, block);
	for(int i=0; i<BG_HEIGHT; i++)
	{
		for (int j=0; j<BG_WIDTH; j++)
		{
			block = SDL_MapRGB(screen->format, colors[bgArray[i][j]][0], colors[bgArray[i][j]][1], colors[bgArray[i][j]][2]);
			SDL_Rect destRect = {(SCREEN_WIDTH-BG_WIDTH*BLOCK_WIDTH)/2+j*BLOCK_WIDTH, (SCREEN_HEIGHT-BG_HEIGHT*BLOCK_HEIGHT)/2+i*BLOCK_HEIGHT, BLOCK_WIDTH, BLOCK_HEIGHT};
			SDL_FillRect(screen, &destRect, block);
		}
	}
	if(SDL_Flip(screen) == -1)
	{
		return false;
	}
}

#pragma region Timer
//The timer
class Timer
{
private:
	//The clock time when the timer started
	int startTicks;

	//The ticks stored when the timer was paused
	int pausedTicks;

	//The timer status
	bool paused;
	bool started;

public:
	//Initializes variables
	Timer();

	//The various clock actions
	void start();
	void stop();
	void pause();
	void unpause();

	//Gets the timer's time
	int get_ticks();

	//Checks the status of the timer
	bool is_started();
	bool is_paused();
};


Timer::Timer()
{
	//Initialize the variables
	startTicks = 0;
	pausedTicks = 0;
	paused = false;
	started = false;
}

void Timer::start()
{
	//Start the timer
	started = true;

	//Unpause the timer
	paused = false;

	//Get the current clock time
	startTicks = SDL_GetTicks();
}

void Timer::stop()
{
	//Stop the timer
	started = false;

	//Unpause the timer
	paused = false;
}

void Timer::pause()
{
	//If the timer is running and isn't already paused
	if( ( started == true ) && ( paused == false ) )
	{
		//Pause the timer
		paused = true;

		//Calculate the paused ticks
		pausedTicks = SDL_GetTicks() - startTicks;
	}
}

void Timer::unpause()
{
	//If the timer is paused
	if( paused == true )
	{
		//Unpause the timer
		paused = false;

		//Reset the starting ticks
		startTicks = SDL_GetTicks() - pausedTicks;

		//Reset the paused ticks
		pausedTicks = 0;
	}
}

int Timer::get_ticks()
{
	//If the timer is running
	if( started == true )
	{
		//If the timer is paused
		if( paused == true )
		{
			//Return the number of ticks when the timer was paused
			return pausedTicks;
		}
		else
		{
			//Return the current time minus the start time
			return SDL_GetTicks() - startTicks;
		}
	}

	//If the timer isn't running
	return 0;
}

bool Timer::is_started()
{
	return started;
}

bool Timer::is_paused()
{
	return paused;
}

#pragma endregion


int main( int argc, char* args[] )
{
	//Quit flag
	bool quit = false;

	//Initialize
	if( init() == false )
	{
		return 1;
	}


	if(!showBg())
		return 1;

	return 0;
}